const gulp = require('gulp'),
  path = require('path'),
  rename = require('gulp-rename'),
  minifycss = require('gulp-minify-css'),
  htmlmin = require('gulp-htmlmin'),
  rev = require('gulp-rev'),
  revCollector = require('gulp-rev-collector'),
  uglify = require('gulp-uglify'),
  del = require('del'),
  connect = require('gulp-connect');

// 配置
const config = {
  buildBasePath: 'dist',
  sourcePath: './',
  host: 'localhost',
  port: 3002,
  // 白名单
  excludeDirs: [
    '!node_modules/**',
    '!dist/**',
    '!.git/**',
    '!gulpfile.js',
    '!package.json',
    '!package-lock.json',
    '!log.txt'
  ],
  // 文件类型配置 - 使用通配符匹配所有层级
  fileTypes: {
    fonts: {
      src: '**/*.{ttf,woff,woff2,eot,svg}',
      dest: '',
      revPath: 'rev/fonts'
    },
    css: {
      src: '**/*.css',// 压缩路径
      dest: '',// 压缩后路径
      revPath: 'rev/css',// 压缩后.json版本文件路径
      processor: minifycss()// 压缩方法
    },
    img: {
      src: '**/*.{png,jpg,jpeg,gif,ico,svg,webp}',
      dest: '',
      revPath: 'rev/img'
    },
    video: {
      src: '**/*.{mp4,avi,mov,mkv,webm,flv}',
      dest: '',
      revPath: 'rev/video'
    },
    audio: {
      src: '**/*.{mp3,wav,aiff,flac,m4a,aac,ape,ogg}',
      dest: '',
      revPath: 'rev/audio'
    },
    js: {
      src: '**/*.js',
      dest: '',
      revPath: 'rev/js',
      processor: uglify()
    },
    html: {
      src: '**/*.html',
      dest: '',
      revPath: 'rev/html',
      processor: htmlmin({ collapseWhitespace: true })
    }
  }
};

// 获取所有需要监听的文件模式（不限制层级）
function getWatchPatterns() {
  const patterns = [];
  Object.keys(config.fileTypes).forEach(type => {
    patterns.push(config.fileTypes[type].src);
  })
  
  return [...patterns, ...config.excludeDirs];
}

// 启动开发服务器
gulp.task('server', function(done) {
  connect.server({
    root: config.sourcePath,
    port: config.port,
    livereload: true,
    host: config.host,
    fallback: 'index.html'
  });
  done();
});

// 重新加载浏览器
gulp.task('reload', function(done) {
  const patterns = getWatchPatterns().filter(pattern => !pattern.startsWith('!'));
  gulp.src(patterns, { read: false })
    .pipe(connect.reload());
  console.log('浏览器已刷新');
  done();
});

// 监听文件变化（所有层级）
gulp.task('watch', function(done) {
  const patterns = getWatchPatterns();
  
  gulp.watch(patterns, gulp.series('reload'));
  
  // 添加文件变化日志
  const watcher = gulp.watch(patterns);
  watcher.on('change', function(filePath) {
    console.log('文件变化:', filePath);
  });
  
  watcher.on('add', function(filePath) {
    console.log('文件新增:', filePath);
  });
  
  watcher.on('unlink', function(filePath) {
    console.log('文件删除:', filePath);
  });
  
  done();
});

// 生产构建任务（支持所有层级）
gulp.task('build', gulp.series(
  function clean() {
    return del([config.buildBasePath]);
  },
  
  function processAllFiles(done) {
    const tasks = [];
    
    // 处理各种文件类型
    Object.keys(config.fileTypes).forEach(type => {
      const task = function processFileType() {
        const fileConfig = config.fileTypes[type];
        let stream = gulp.src([fileConfig.src, ...config.excludeDirs], { allowEmpty: true });
        
        if (fileConfig.processor) {
          stream = stream.pipe(fileConfig.processor);
        }
        if (['.html'].includes(path.extname(fileConfig.src))) {
          return stream
          .pipe(gulp.dest(path.join(config.buildBasePath, fileConfig.dest)))
        }
        return stream
          .pipe(rev())
          .pipe(gulp.dest(path.join(config.buildBasePath, fileConfig.dest)))
          .pipe(rename({ dirname: '' }))
          .pipe(rev.manifest())
          .pipe(gulp.dest(path.join(config.buildBasePath, fileConfig.revPath)));
      };
      tasks.push(task);
    });
    
    if (tasks.length === 0) {
      return done();
    }
    
    gulp.parallel(...tasks)(done);
  },
  
  function replaceVersions(done) {
    const revJsonFiles = [];
    const fileTypes = Object.keys(config.fileTypes);
    
    fileTypes.forEach(type => {
      const revPath = path.join(config.buildBasePath, config.fileTypes[type].revPath, '*.json');
      revJsonFiles.push(revPath);
    });
    
    const cssTask = function() {
      const cssFiles = path.join(config.buildBasePath, '**/*.css');
      return gulp.src([...revJsonFiles, cssFiles], { allowEmpty: true })
        .pipe(revCollector())
        .pipe(gulp.dest(config.buildBasePath));
    };
    
    const jsTask = function() {
      const jsFiles = path.join(config.buildBasePath, '**/*.js');
      return gulp.src([...revJsonFiles, jsFiles], { allowEmpty: true })
        .pipe(revCollector())
        .pipe(gulp.dest(config.buildBasePath));
    };
    
    const htmlTask = function() {
      const htmlFiles = path.join(config.buildBasePath, '**/*.html');
      return gulp.src([...revJsonFiles, htmlFiles], { allowEmpty: true })
        .pipe(revCollector())
        .pipe(gulp.dest(config.buildBasePath));
    };
    
    gulp.parallel(cssTask, jsTask, htmlTask)(done);
  },
  
  function cleanRev() {
    return del([path.join(config.buildBasePath, 'rev')]);
  }
));

// 开发任务
gulp.task('dev', gulp.series('server', 'watch'));

gulp.task('default', gulp.series('dev'));

// 调试任务：显示监听的文件
gulp.task('debug', function(done) {
  const patterns = getWatchPatterns();
  console.log('=== 监听模式详情 ===');
  patterns.forEach((pattern, index) => {
    console.log(`${index + 1}. ${pattern}`);
  });
  console.log('====================');
  done();
});

module.exports = { config };